package nacos

import (
	"encoding/json"
	"fmt"
	"github.com/nacos-group/nacos-sdk-go/clients"
	"github.com/nacos-group/nacos-sdk-go/vo"
	"github.com/spf13/viper"
	"strings"

	"github.com/nacos-group/nacos-sdk-go/common/constant"
	"log"
	"os"
)

var (
	defaultConfig *viper.Viper
)


func Configure(DataId, conn, Group string) *RedisChe {
	switch conn {
	case "redis":
		host := GetConfig(DataId, Group)
		return newRedis(host) //获redis链接
	default:
		return nil
	}
}



//获取redis数据信息
func newRedis(host *viper.Viper) *RedisChe {
	st := new(RedisChe)
	st.Host = host.GetString("Host")
	st.Pass = host.GetString("Pass")
	st.RedisType = host.GetString("RedisType")
	st.Db = host.GetString("Db")
	return st
}


func GetConfig(DataId string, group string) *viper.Viper {

	return initNaConfig(DataId, group)
}

//加载naCos配置中心, 获取redis连接信息
func initNaConfig(DataId string, group string) *viper.Viper {
	config := getNaCosConfig()
	var lhn = new(LocalHostNaCos)
	MarshalArrayString(config.Get("Nacos.IP"), &lhn.NaCosIp)
	MarshalArrayInt(config.Get("Nacos.Port"), &lhn.NaCosPort)
	MarshalArrayString(config.Get("Nacos.NamespaceId"), &lhn.NamespaceId)
	if len(lhn.NaCosIp) == len(lhn.NaCosPort) && len(lhn.NaCosIp) == len(lhn.NamespaceId) {
		for i, v := range lhn.NaCosIp {
			defaultConfig = viper.New()
			defaultConfig.SetConfigType("yaml")
			implement := true

			//配置模型
			serverConfigs := []constant.ServerConfig{
				{IpAddr: v, Port: lhn.NaCosPort[i]},
			}

			//配置naCos客户端
			naCosClient, err := clients.NewConfigClient(
				vo.NacosClientParam{
					ClientConfig: &constant.ClientConfig{
						TimeoutMs:   5000,
						NamespaceId: lhn.NamespaceId[i], // 命名空间 名称id,例如 dev,Prod
					},
					ServerConfigs: serverConfigs,
				},
			)
			if err != nil {
				implement = false
				log.Fatal("nacos初始化错误:", err)
			}

			// GetConfig 用于从 nacos 服务器获取配置
			content, err := naCosClient.GetConfig(vo.ConfigParam{DataId: DataId, Group: group})
			if err != nil {
				implement = false
				fmt.Println("nacos读取配置错误:" + content + ",请检查Nacos是否在线")
			}

			//获取配置信息
			err = defaultConfig.ReadConfig(strings.NewReader(content))
			if err != nil {
				implement = false
				log.Fatalln("Viper解析配置失败:", err)
			}

			// ListenConfig 用于监听 naCos配置变化
			err = naCosClient.ListenConfig(vo.ConfigParam{
				DataId: DataId,
				Group:  group,
				OnChange: func(namespace, group, dataId, data string) {
					fmt.Println("config changed group:" + group + ", dataId:" + dataId + ", content:" + data)
					err = defaultConfig.ReadConfig(strings.NewReader(data))
					if err != nil {
						implement = false
						log.Fatalln("Viper解析配置失败:", err)
					}
				},
			})
			if implement == true {
				break
			}
		}
	} else {
		log.Fatalln("Nacos的参数配置数量不一致")
	}
	return defaultConfig
}

//获取当前目录下的配置文件
func getNaCosConfig() *viper.Viper {
	v := viper.New()
	path, _ := os.Getwd()
	v.SetConfigName("nacosconfig")
	v.AddConfigPath(path + "/config")
	v.SetConfigType("yaml")
	err := v.ReadInConfig()
	if err != nil {
		log.Println("加载配置文件错误: ", err)
		return nil
	}
	return v
}

func MarshalArrayString(data interface{}, st *[]string) {
	resByre, _ := json.Marshal(data)
	_ = json.Unmarshal(resByre, &st)
}

func MarshalArrayInt(data interface{}, st *[]uint64) {
	resByre, _ := json.Marshal(data)
	_ = json.Unmarshal(resByre, &st)
}
